home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / lib / directX / dx.cpp next >
Encoding:
C/C++ Source or Header  |  2000-12-12  |  10.4 KB  |  460 lines

  1. #include "../Fly3D.h"
  2.  
  3. FLY_API directX *directx=0;
  4.  
  5. FLY_API void init_directx()
  6. {
  7.     free_directx();
  8.     directx=new directX();
  9. }
  10.  
  11. FLY_API void free_directx()
  12. {
  13.     if (directx)
  14.         delete directx;
  15.     directx=0;
  16. }
  17.  
  18. void directX::send_message(mp_msg *data,int len,DWORD dpid)
  19. {
  20.     if (lpDP)
  21.         if (data->type&FLYMP_GUARANTEED)
  22.             if (dpid==0)
  23.                 lpDP->Send(players[0].dpid,DPID_ALLPLAYERS,DPSEND_GUARANTEED,data,len);
  24.             else lpDP->Send(players[0].dpid,dpid,DPSEND_GUARANTEED,data,len);
  25.         else
  26.             if (dpid==0)
  27.                 lpDP->Send(players[0].dpid,DPID_ALLPLAYERS,0,data,len);
  28.             else lpDP->Send(players[0].dpid,dpid,0,data,len);
  29. }
  30.  
  31. BOOL FAR PASCAL EnumAddressCallback(
  32.     REFGUID guidDataType,DWORD dwDataSize,
  33.     LPCVOID lpData,LPVOID lpContext)
  34. {
  35.     if (guidDataType==DPAID_INet)
  36.     {
  37.         if (((char *)lpContext)[0]!=0)
  38.             strcat((char *)lpContext," , ");
  39.         strcat((char *)lpContext,(char *)lpData);
  40.     }
  41.     return 1;
  42. }
  43.  
  44. char *directX::get_player_address(DWORD dpid)
  45. {
  46.     static char buf[1024],str[256];
  47.     str[0]=0;
  48.     if (lpDP)
  49.     {
  50.         DWORD size=1024;
  51.         lpDP->GetPlayerAddress(dpid,buf,&size);
  52.         lpDPL->EnumAddress(EnumAddressCallback,buf,size,str);
  53.     }
  54.     return str;
  55. }
  56.  
  57. int directX::get_num_messages()
  58. {
  59.     DWORD count=0;
  60.     if (lpDP)
  61.         lpDP->GetMessageCount(players[0].dpid,&count);    
  62.     return count;
  63. }
  64.  
  65. mp_msg *directX::get_message(DWORD *size)
  66. {
  67.     if (lpDP==0)
  68.         return 0;
  69.     static mp_msg msg;
  70.     DWORD idfrom;
  71.     DWORD idto=players[0].dpid;
  72.     if (DP_OK==lpDP->Receive(&idfrom,&idto,DPRECEIVE_TOPLAYER,&msg.type,size))
  73.         return &msg;
  74.     return 0;
  75. }
  76.  
  77. int directX::init_multiplayer(char *netaddress)
  78. {
  79.     DPCOMPOUNDADDRESSELEMENT addressElements[3];
  80.     DWORD dwElementCount=0;
  81.     char address[512];
  82.     DWORD size=512;
  83.  
  84.     free_multiplayer();
  85.     CoCreateInstance(CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER,
  86.           IID_IDirectPlay3A,(LPVOID*)&lpDP);
  87.     if (lpDP)
  88.         {
  89.         CoCreateInstance(CLSID_DirectPlayLobby, NULL, CLSCTX_INPROC_SERVER,
  90.             IID_IDirectPlayLobby2A, (LPVOID *) &lpDPL);
  91.  
  92.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  93.         addressElements[dwElementCount].dwDataSize = sizeof(GUID);
  94.         addressElements[dwElementCount].lpData = (LPVOID) &DPSPGUID_TCPIP;
  95.         dwElementCount++;
  96.         
  97.         if (netaddress)
  98.             {
  99.             addressElements[dwElementCount].guidDataType = DPAID_INet;
  100.             addressElements[dwElementCount].dwDataSize = strlen(netaddress)+1;
  101.             addressElements[dwElementCount].lpData = netaddress;
  102.             dwElementCount++;
  103.             }
  104.  
  105.         lpDPL->CreateCompoundAddress(
  106.             addressElements, dwElementCount,
  107.             address, &size);
  108.  
  109.         if (DP_OK==lpDP->InitializeConnection(address,0))
  110.             return 1;
  111.         }
  112.     free_multiplayer();
  113.     return 0;
  114. }
  115.  
  116. void directX::free_multiplayer()
  117. {
  118.     if (lpDPL)
  119.         lpDPL->Release();
  120.     if (lpDP)
  121.         lpDP->Release();
  122.     if (lpSD)
  123.         delete lpSD;
  124.     lpSD=0;
  125.     lpDP=0;
  126.     lpDPL=0;
  127.     nplayers=0;
  128.     mpmode=FLYMP_NOMP;
  129. }
  130.  
  131. BOOL FAR PASCAL EnumPlayersCallback(
  132.     DPID dpId,DWORD dwPlayerType,
  133.     LPCDPNAME lpName,DWORD dwFlags,    LPVOID lpContext)
  134. {
  135.     directX *dx=(directX *)lpContext;
  136.  
  137.     if (dpId!=DPID_SERVERPLAYER && dpId!=dx->players[0].dpid)
  138.     {
  139.         strcpy(dx->players[dx->nplayers].name,lpName->lpszShortNameA);
  140.         dx->players[dx->nplayers].dpid=dpId;
  141.         dx->nplayers++;
  142.     }
  143.     return 1;
  144. }
  145.  
  146. int directX::join_game(LPGUID game_guid,char *player_name)
  147. {
  148.     if (lpDP==0) return 0;
  149.  
  150.     mpmode=0;
  151.  
  152.     lpSD=new DPSESSIONDESC2;
  153.     memset(lpSD,0,sizeof(DPSESSIONDESC2));
  154.     
  155.     lpSD->guidInstance=guidInstance=*game_guid;
  156.     lpSD->dwSize=sizeof(DPSESSIONDESC2);
  157.     if (DP_OK!=lpDP->Open(lpSD,DPOPEN_JOIN))
  158.         return 0;
  159.  
  160.     nplayers=1;
  161.     strcpy(players[0].name,player_name);
  162.     players[0].data=0;
  163.  
  164.     DPNAME pn;
  165.     pn.dwFlags=0;
  166.     pn.dwSize=sizeof(DPNAME);
  167.     pn.lpszShortNameA=players[0].name;
  168.     pn.lpszLongNameA=players[0].name;
  169.     lpDP->CreatePlayer(&players[0].dpid,&pn,0,(void *)&players[0],sizeof(player_data),0);
  170.  
  171.     lpDP->EnumPlayers(0,EnumPlayersCallback,this,DPENUMPLAYERS_ALL);
  172.  
  173.     mpmode=1;
  174.  
  175.     return players[0].dpid;
  176. }
  177.  
  178. int directX::create_game(LPGUID app_guid,char *game_name)
  179. {
  180.     if (lpDP==0) return 0;
  181.  
  182.     lpSD=new DPSESSIONDESC2;
  183.     memset(lpSD,0,sizeof(DPSESSIONDESC2));
  184.     
  185.     CoCreateGuid(&guidInstance);
  186.     lpSD->guidInstance=guidInstance;
  187.  
  188.     lpSD->dwSize=sizeof(DPSESSIONDESC2);
  189.     lpSD->dwFlags=
  190.         DPSESSION_CLIENTSERVER|
  191.         DPSESSION_KEEPALIVE|
  192.         DPSESSION_NODATAMESSAGES;
  193.     lpSD->guidApplication=*app_guid;
  194.     lpSD->dwMaxPlayers=FLYMP_MAXPLAYERS;
  195.     lpSD->dwCurrentPlayers=0;
  196.     lpSD->lpszSessionNameA=game_name;
  197.  
  198.     if (DP_OK!=lpDP->Open(lpSD,DPOPEN_CREATE))
  199.         return 0;
  200.  
  201.     DPNAME pn;
  202.     pn.dwFlags=0;
  203.     pn.dwSize=sizeof(DPNAME);
  204.     nplayers=1;
  205.     players[0].data=0;
  206.     strcpy(players[0].name,"server");
  207.     pn.lpszShortNameA="server";
  208.     pn.lpszLongNameA="server";
  209.     lpDP->CreatePlayer(&players[0].dpid,&pn,0,0,0,DPPLAYER_SERVERPLAYER);
  210.     mpmode=2;
  211.  
  212.     return 1;
  213. }
  214.  
  215. BOOL FAR PASCAL EnumSessionsCallback(
  216.     LPCDPSESSIONDESC2 lpThisSD,    LPDWORD lpdwTimeOut,
  217.     DWORD dwFlags,LPVOID lpContext)
  218. {
  219.     if (lpThisSD==0) return 0;
  220.     mp_games *g=(mp_games *)lpContext;
  221.     strcpy(g->name[g->num],lpThisSD->lpszSessionNameA);
  222.     g->guid[g->num]=lpThisSD->guidInstance;
  223.     g->num_players[g->num]=lpThisSD->dwCurrentPlayers-1;
  224.     g->num++;
  225.     return 1;
  226. }
  227.  
  228. mp_games *directX::enum_games(LPGUID app_guid)
  229. {
  230.     if (lpDP==0) return 0;
  231.  
  232.     static mp_games g;
  233.     g.num=0;
  234.  
  235.     DPSESSIONDESC2 sd;
  236.     memset(&sd,0,sizeof(DPSESSIONDESC2));
  237.     sd.dwSize=sizeof(DPSESSIONDESC2);
  238.     sd.guidApplication=*app_guid;
  239.     lpDP->EnumSessions(&sd,FLYMP_BROWSETIME,EnumSessionsCallback,&g,DPENUMSESSIONS_ALL);
  240.  
  241.     return &g;
  242. }
  243.  
  244. void directX::Init()
  245. {
  246.     HRESULT hr;
  247.     CoInitialize(0);
  248.     hr = DirectInputCreate(hFlyInst, DIRECTINPUT_VERSION, &lpDI, NULL);
  249.     if (lpDI!=NULL)
  250.     {
  251.     hr = lpDI->CreateDevice(GUID_SysKeyboard, &lpKeyboard, NULL);
  252.     if (lpKeyboard)
  253.         {
  254.         hr = lpKeyboard->SetDataFormat(&c_dfDIKeyboard);
  255.         hr = lpKeyboard->SetCooperativeLevel(hFlyWnd, DSSCL_NORMAL);//DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);
  256.         }
  257.  
  258.     hr = lpDI->CreateDevice(GUID_SysMouse, &lpMouse, NULL);
  259.     if (lpMouse)
  260.         {
  261.         hr = lpMouse->SetDataFormat(&c_dfDIMouse);
  262.         hr = lpMouse->SetCooperativeLevel(hFlyWnd, DSSCL_NORMAL);//DISCL_NONEXCLUSIVE|DISCL_FOREGROUND);
  263.         }
  264.     }
  265.  
  266.     if (lpKeyboard) lpKeyboard->Acquire();
  267.     if (lpMouse) lpMouse->Acquire();
  268.  
  269.     hr = DirectSoundCreate(NULL,&lpDSound,NULL);
  270.     if (lpDSound!=NULL)
  271.     {
  272.     lpDSound->SetCooperativeLevel(hFlyWnd,DSSCL_NORMAL);
  273.     
  274.     DSBUFFERDESC desc;
  275.     memset(&desc,0,sizeof(DSBUFFERDESC));
  276.     desc.dwSize=sizeof(DSBUFFERDESC);
  277.     desc.dwFlags=DSBCAPS_CTRL3D|DSBCAPS_CTRLVOLUME|DSBCAPS_PRIMARYBUFFER;
  278.     lpDSound->CreateSoundBuffer(&desc,&lpDS3dPrimBuf,0);
  279.  
  280.     WAVEFORMATEX format;
  281.     format.wFormatTag=WAVE_FORMAT_PCM;
  282.     format.nChannels=1;
  283.     format.nSamplesPerSec=22050;
  284.     format.wBitsPerSample=16;
  285.     format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;
  286.     format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign;
  287.     format.cbSize=0;
  288.     lpDS3dPrimBuf->SetFormat(&format);
  289.  
  290.     lpDS3dPrimBuf->QueryInterface(IID_IDirectSound3DListener, (void **)(&lpDS3dListener));
  291.  
  292.     lpDS3dListener->SetDistanceFactor(0.1f,DS3D_IMMEDIATE);
  293.     lpDS3dListener->SetDopplerFactor(0.1f,DS3D_IMMEDIATE);
  294.     lpDS3dListener->SetRolloffFactor(0.1f,DS3D_IMMEDIATE);
  295.     }
  296. }
  297.  
  298. void directX::Release()
  299. {
  300.     free_multiplayer();
  301.     if (lpKeyboard) 
  302.         {
  303.         lpKeyboard->Unacquire();
  304.         lpKeyboard->Release();
  305.         lpKeyboard = NULL;
  306.         }
  307.     if (lpMouse) 
  308.         {
  309.         lpMouse->Unacquire();
  310.         lpMouse->Release();
  311.         lpMouse = NULL;
  312.         }
  313.     if (lpDI) 
  314.         {
  315.         lpDI->Release();
  316.         lpDI = NULL;
  317.         }
  318.     if (lpDSound)
  319.         {
  320.         lpDS3dListener->Release();
  321.         lpDS3dPrimBuf->Release();
  322.         lpDSound->Release();
  323.         lpDSound = NULL;
  324.         }
  325.     CoUninitialize();
  326. }
  327.  
  328. int directX::load_wav_file(LONG cchBuffer, HPSTR pchBuffer, LPDIRECTSOUNDBUFFER *buf, LPDIRECTSOUND3DBUFFER *buf3d)
  329. {
  330.     if (lpDSound==0)
  331.         return 0;
  332.  
  333.     UINT Size;
  334.     DWORD Samples;
  335.     WAVEFORMATEX *Info;
  336.     BYTE *Data;
  337.     DSBUFFERDESC desc;
  338.  
  339.     if (WaveLoadFileB(cchBuffer,pchBuffer,&Size,&Samples,&Info,&Data))
  340.         return 0;
  341.     desc.dwSize=sizeof(DSBUFFERDESC);
  342.     desc.dwFlags=DSBCAPS_STATIC|DSBCAPS_CTRLVOLUME;
  343.     if (buf3d)
  344.         desc.dwFlags|=DSBCAPS_CTRL3D;//|DSBCAPS_MUTE3DATMAXDISTANCE;
  345.     desc.dwBufferBytes=Size;
  346.     desc.lpwfxFormat=Info;
  347.     desc.dwReserved=0;
  348.  
  349.     lpDSound->CreateSoundBuffer(&desc,buf,0);
  350.     if (*buf)
  351.         {
  352.         LPVOID blk1,blk2;
  353.         DWORD size1,size2;
  354.  
  355.         (*buf)->QueryInterface(IID_IDirectSound3DBuffer,(void **)(buf3d));
  356.  
  357.         (*buf)->Lock(0,Size,&blk1,&size1,&blk2,&size2,0);
  358.         CopyMemory(blk1,Data,size1);
  359.         if (Size>size1)
  360.             CopyMemory(blk2,Data+size1,size2);
  361.         (*buf)->Unlock(blk1,size1,blk2,size2);
  362.         }
  363.  
  364.     Size=Size*1000/Info->nAvgBytesPerSec;
  365.     if (Info)
  366.         GlobalFree(Info);
  367.     if (Data)
  368.         GlobalFree(Data);
  369.     Info=0;
  370.     Data=0;
  371.     return Size;
  372. }
  373.  
  374. void directX::get_input()
  375. {
  376.     if (lpDI==0) return;
  377.  
  378.     HRESULT hr;
  379.  
  380.     if (lpKeyboard) 
  381.     {
  382.         hr = lpKeyboard->GetDeviceState(sizeof(diks), diks);
  383.         if (hr == DIERR_INPUTLOST) 
  384.             {
  385.             hr = lpKeyboard->Acquire();
  386.             if (SUCCEEDED(hr)) 
  387.                 hr = lpKeyboard->GetDeviceState(sizeof(diks), diks);
  388.             }
  389.     }
  390.     if (lpMouse) 
  391.     {
  392.         hr=lpMouse->GetDeviceState(sizeof(DIMOUSESTATE), &dims);
  393.         if (hr == DIERR_INPUTLOST) 
  394.             {
  395.             hr = lpMouse->Acquire();
  396.             if (SUCCEEDED(hr)) 
  397.                 hr = lpMouse->GetDeviceState(sizeof(DIMOUSESTATE), &dims);
  398.             }
  399.     }
  400. }
  401.  
  402. void directX::set_listener(float *pos,float *vel,float *Y,float *Z)
  403. {
  404.     if (lpDS3dListener)
  405.     {
  406.         if (pos)
  407.         lpDS3dListener->SetPosition(
  408.             pos[0],pos[1],pos[2],
  409.             DS3D_DEFERRED);
  410.         if (vel)
  411.         lpDS3dListener->SetVelocity(
  412.             vel[0],vel[1],vel[2],
  413.             DS3D_DEFERRED);
  414.         if (Y && Z)
  415.         lpDS3dListener->SetOrientation(
  416.             Z[0],Z[1],Z[2],
  417.             Y[0],Y[1],Y[2],
  418.             DS3D_DEFERRED);
  419.         lpDS3dListener->CommitDeferredSettings();
  420.     }
  421. }
  422.  
  423. LPDIRECTSOUNDBUFFER directX::clone_sound(LPDIRECTSOUNDBUFFER buf)
  424. {
  425.     if (lpDSound==0) return 0;
  426.     static LPDIRECTSOUNDBUFFER dup_buf;
  427.     lpDSound->DuplicateSoundBuffer(buf,&dup_buf);
  428.     return dup_buf;
  429. }
  430.  
  431. int directX::add_player(char *name,DWORD dpid,void *data)
  432. {
  433.     if (nplayers<FLYMP_MAXPLAYERS)
  434.     {
  435.         strcpy(players[nplayers].name,name);
  436.         players[nplayers].dpid=dpid;
  437.         players[nplayers].data=data;
  438.         return nplayers++;
  439.     }
  440.     else return -1;
  441. }
  442.  
  443. void *directX::remove_player(int i)
  444. {
  445.     if (i<nplayers)
  446.     {
  447.         void *data=players[i].data;
  448.         memcpy(&players[i],&players[i+1],sizeof(player_data)*(nplayers-i-1));
  449.         nplayers--;
  450.         return data;
  451.     }
  452.     else return 0;
  453. }
  454.  
  455. void directX::set_master_volume(int volume)
  456. {
  457.     if (lpDS3dPrimBuf)
  458.         lpDS3dPrimBuf->SetVolume(volume);
  459. }
  460.